package com.cjd.view.audio;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;

import com.cjd.common.R;

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @Author chenjidong
 * @email 374122600@qq.com
 * created 2019/7/31
 * description 模拟音频 频谱
 */
public class AudioSpectrumView extends View implements Handler.Callback {
    private Paint paint;
    private int viewWidth, viewHeight;
    private int activeColor, normalColor;
    private float[] lines;
    private float lineWidth;
    private int lineInterval;
    private int currentProgress = 0;
    private int startProgress = 0, endProgress = 100;
    private Handler handler;
    private Random random;
    private boolean isPlaying;

    public AudioSpectrumView(Context context) {
        super(context);
        init();
    }

    public AudioSpectrumView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AudioSpectrumView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) {
            viewWidth = MeasureSpec.getSize(widthMeasureSpec);
        }

        if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.UNSPECIFIED) {
            viewHeight = MeasureSpec.getSize(heightMeasureSpec);
        }
        initLines();
    }


    private void initLines() {
        lines = new float[viewWidth];
        Random random = new Random();
        int max = viewHeight / 4 * 3;
        int min = max / 2;
        for (int i = 0; i < lines.length; i++) {
            int randomNum = random.nextInt(max - min + 1) + min;
            lines[i] = randomNum;
        }
    }

    private void init() {
        normalColor = getResources().getColor(R.color.audio_normal_color);
        activeColor = getResources().getColor(R.color.audio_active_color);
        lineWidth = dp2px(2);
        lineInterval = dp2px(2);
        paint = new Paint();
        paint.setColor(activeColor);
        paint.setStrokeWidth(lineWidth);
        paint.setStyle(Paint.Style.STROKE);

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                if (isPlaying)
                    handler.sendEmptyMessage(1);
            }
        }, 0, 200);
        handler = new Handler(this);
        random = new Random();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        LogUtils.debug("--->onDraw:" + startProgress + " current:" + currentProgress);
        float centerY = viewHeight / 2f;
        float startWidth = viewWidth / 100f * startProgress;
        float currentWidth = startWidth + (viewWidth / 100f * currentProgress);
        float endWidth = viewWidth / 100f * endProgress;

        for (int i = 0; i < viewWidth; i += (lineWidth + lineInterval)) {
            paint.setColor(normalColor);
            float line = lines[i] / 2;

            if (isPlaying && i >= startWidth && i <= endWidth) {
                int remaining = (int) ((centerY - line) / 2);
                if (i % 2 == 0) {
                    line -= random.nextInt(remaining);
                } else {
                    line += random.nextInt(remaining);
                }
            }

            canvas.drawLine(i, centerY - line, i, centerY + line, paint);
            if (i >= startWidth && i <= currentWidth && i <= endWidth) {
                paint.setColor(activeColor);
                canvas.drawLine(i, centerY - line, i, centerY + line, paint);
            }
        }
    }

    public float getStartWidth() {
        return (viewWidth / 100f * getStartProgress());
    }

    public float getEndWidth() {
        return (viewWidth / 100f * endProgress);
    }

    public int getStartProgress() {
        return startProgress;
    }

    public int getEndProgress() {
        return endProgress;
    }

    public int getCurrentProgress() {
        return currentProgress;
    }

    public boolean isPlaying() {
        return isPlaying;
    }

    public void setPlaying(boolean playing) {
        isPlaying = playing;
    }

    public void setCurrentProgress(int currentProgress) {
        if (this.currentProgress == currentProgress)
            return;
        this.currentProgress = currentProgress;
        if (this.currentProgress > 100)
            this.currentProgress = 100;
        else if (this.currentProgress < 0)
            this.currentProgress = 0;
        if (!isPlaying)
            invalidate();
    }

    public void setStartProgress(int startProgress) {
        this.startProgress = startProgress;
        if (this.startProgress > 100)
            this.startProgress = 100;
        else if (this.startProgress < 0)
            this.startProgress = 0;

        if (!isPlaying)
            invalidate();
    }

    public void setEndProgress(int endProgress) {
        this.endProgress = endProgress;
        if (this.endProgress > 100)
            this.endProgress = 100;
        if (!isPlaying)
            invalidate();
    }

    private int dp2px(float dpValue) {
        float density = getResources().getDisplayMetrics().density;
        return (int) (density * dpValue + 0.5f);
    }

    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case 1:
                invalidate();
                break;
        }
        return false;
    }
}
